package tt.dz.egobus.servicemanager.business.filter;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import tt.dz.egobus.api.managerservice.manager.AddressUnit;
import tt.dz.egobus.api.managerservice.manager.RequestTask;
import tt.dz.egobus.api.managerservice.manager.UserRequestAddressInfo;
import tt.dz.egobus.api.managerservice.manager.UserRequestTypeInfo;
import tt.dz.egobus.servicemanager.bean.SpringConfigConstant;
import tt.dz.egobus.servicemanager.business.distance.PointFilter;
import tt.dz.egobus.servicemanager.business.point.BusPoint;
import tt.dz.egobus.servicemanager.business.point.CommonPoint;
import tt.dz.egobus.servicemanager.business.point.PointAlgorithmHelp;
import tt.dz.egobus.servicemanager.entities.DriverRegisterBusRelative;
import tt.dz.egobus.servicemanager.service.GrabRedisBusinessWorkCacheService;

import java.util.Arrays;
import java.util.Comparator;

/**
 * @author Anson
 * @date 17-8-29
 * @name 及时打车的司机匹配器
 * @since 1.0.7
 */
public class RightNowBusPointMatchHandler implements UserRequestBusPointMatchHandler {

    private static final Logger LOGGER = LoggerFactory.getLogger(RightNowBusPointMatchHandler.class);

    private final GrabRedisBusinessWorkCacheService businessWorkCacheService;
    private final RequestTask requestTask;
    private final SpringConfigConstant springConfigConstant;

    public RightNowBusPointMatchHandler(GrabRedisBusinessWorkCacheService businessWorkCacheService,
                                        RequestTask requestTask, SpringConfigConstant springConfigConstant) {
        this.businessWorkCacheService = businessWorkCacheService;
        this.requestTask = requestTask;
        this.springConfigConstant = springConfigConstant;
    }

    @Override
    public BusPoint[] filter(PointFilter filter) {
        BusPoint[] bp = new BusPoint[0];
        PointChainFilter originalFilter = this.getFilter();
        if (filter != null) {
            originalFilter.add(filter);
        }
        UserRequestAddressInfo userRequestAddressInfo = requestTask.getUserRequestAddressInfo();
        AddressUnit userOnStartAddress = userRequestAddressInfo.getRequestOnStartAddress();
        double x = userOnStartAddress.getX();
        double y = userOnStartAddress.getY();
        BusPoint[] availableBusPoints = businessWorkCacheService.filterMaxLength(x, y, originalFilter,
                DriverRegisterBusRelative.RelativeStatus.ACTIVE);
        if (availableBusPoints == null || availableBusPoints.length == 0) {
            //当前无单可派的时候,范湖车辆繁忙中
            LOGGER.info("当前过滤不存在司机,count={}", availableBusPoints.length);
            return bp;
        }
        LOGGER.info("当前搜索及时打车的过滤司机个数,count={}", availableBusPoints.length);
        Arrays.sort(availableBusPoints, new Comparator<BusPoint>() {
            @Override
            public int compare(BusPoint o1, BusPoint o2) {
                double distance = 0;
                distance = PointAlgorithmHelp.accPointLength(o1, x, y) - PointAlgorithmHelp.accPointLength(o2, x, y);
                return distance == 0 ? 0 : (distance > 0 ? 1 : -1);
            }
        });
        //验证当前系统中是否含有当前业务号
        BusPoint[] bestBusQueue = availableBusPoints;
        return bestBusQueue == null ? bp : bestBusQueue;
    }

    @Override
    public UserRequestTypeInfo.UserRequestType getRequestType() {
        return UserRequestTypeInfo.UserRequestType.NOW;
    }

    private PointChainFilter getFilter() {
        int businessCode = requestTask.getBusinessCode();
        PointChainFilter pointChainFilter = new PointChainFilter();
        Integer maxSearchLimit = springConfigConstant.businessGrabBusDistributeMaxSearchLimit();
        UserRequestAddressInfo userRequestAddressInfo = requestTask.getUserRequestAddressInfo();
        AddressUnit userOnStartAddress = userRequestAddressInfo.getRequestOnStartAddress();
        double x = userOnStartAddress.getX();
        double y = userOnStartAddress.getY();
        pointChainFilter.add(new BusinessCodeValidateFilter(businessCode));
        pointChainFilter.add(new MaxLimitPointFilter(maxSearchLimit, new CommonPoint(x, y)));
        return pointChainFilter;
    }
}
